package com.example.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.ListUtils;
import com.example.domain.fanweiKQ.DkDateEntity;
import com.example.domain.fanweiKQ.HolidayEntity;
import com.example.domain.fanweiKQ.JbtsEntity;
import com.example.domain.fanweiKQ.JiaBanEntity;
import com.example.domain.fanweiKQ.KqBzEntity;
import com.example.domain.vo.JbtsExcel;
import com.example.mapper.KqbbMapper;
import com.example.service.KqbbService;
import com.example.utils.config.CommonConfig;

import lombok.extern.slf4j.Slf4j;

@Service
@Transactional
@Slf4j
public class KqbbServiceImp implements KqbbService {

	@Autowired
	KqbbMapper kqbbMapper;

	@Override
	public List<DkDateEntity> queryDk(String day, String key) {
		// 泛微打卡日期集合
		return kqbbMapper.queryDk(day, key);
	}

	@Override
	public List<HolidayEntity> queryHoliday(String day) {
		// 节假日
		return kqbbMapper.queryHoliday(day);
	}

	@Override
	public List<JiaBanEntity> queryJiaBan(String day) {
		// 加班
		return kqbbMapper.queryJiaBan(day);
	}

	/*
	 * 出勤天数
	 * 
	 * @param day 2023-02
	 */
	public void getCQTS(String day) {
		return;
	}

	@Override
	public List<JiaBanEntity> queryKq(String date) {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * 处理加班流程、加班计划流程数据，变为Map(工号，日期集合) 即jbMap
	 * 
	 * @param jbList
	 * @return
	 */
	private Map<String, List<String>> getJbMap(List<JiaBanEntity> jbList) {
		Map<String, List<String>> jbMap = new HashMap<>();
		for (JiaBanEntity jiaBanEntity : jbList) {
			String workCode = jiaBanEntity.getWorkcode(); // 工号
			String jbDate = jiaBanEntity.getToDate(); // 加班日期
			if (jbMap.containsKey(workCode)) { // 存在更新日期list值
				List<String> newDateList = jbMap.get(workCode);
				newDateList.add(jbDate);
				jbMap.put(workCode, newDateList);
			} else { // 不存在创建日期list值
				List<String> jbDateList = new ArrayList<>();
				jbDateList.add(jbDate);
				jbMap.put(workCode, jbDateList);
			}
		}
		return jbMap;
	}

	/**
	 * 当月所有人打卡记录
	 * 
	 * @param date
	 * @return Map<工号, List<日期>>
	 */
	private Map<String, Set<String>> getDkMap(String date, String key) {
		List<DkDateEntity> firstDkList = kqbbMapper.queryDk(date, key); // 泛微获取到所有人打卡数据
		Map<String, Set<String>> dkMap = new HashMap<>(); // 当月所有人打卡日期
		for (DkDateEntity dkDateEntity : firstDkList) {
			String workCode = dkDateEntity.getWorkcode(); // 工号
			String dkDate = dkDateEntity.getDkdate(); // 打卡日期
			if (dkMap.containsKey(workCode)) { // 存在更新日期set值
				Set<String> newDateList = dkMap.get(workCode);
				newDateList.add(dkDate);
				dkMap.put(workCode, newDateList);
			} else { // 不存在创建日期list值
				Set<String> dkDateList = new HashSet<>();
				dkDateList.add(dkDate);
				dkMap.put(workCode, dkDateList);
			}
		}

		return dkMap;
	}

	/**
	 * 以董事长为基准，获取当月应考勤日期
	 */

	@Override
	public List<KqBzEntity> querykqBz(String date) {
		return kqbbMapper.queryKqBz(date);
	}

	/**
	 * 加班流程集合
	 * 
	 * @param day
	 * @return
	 */
	private List<JiaBanEntity> queryJiaBanLiuCheng(String day) {
		return kqbbMapper.queryJiaBanLiuCheng(day);
	}

	/**
	 * 交补天数 思路： 获取部分—— 最终获取dkMap(全员打卡情况),gzrList(工作日list),xxrList(休息日list),
	 * jbList(全员加班情况)
	 * 
	 * 1、获取当月所有人打卡日期，放入Map<工号, List<日期>>也就是dkMap；
	 * 2、获取当月日期情况，工作日放入gzrList,周末和节假日放入xxrList；
	 * 3、获取当月所有加班流程和加班计划流程，放入List<JiaBanEntity>也就是jbList；
	 * 
	 * ///计算部分：1、遍历每个人打卡数据 2、循环每天判断是否是节假日打卡 3、不是-跳过 4、是-查询当天是否有加班 5、是-跳过 6、否-扣除当天
	 * 
	 */
	@Override
	public List<JbtsEntity> queryJbts(String date, String key) {
		// 所有人打卡记录 Map(工号,打卡日期集合)
		Map<String, String> worknamAndNameMap = new HashMap<>(); // <工号:姓名>
		List<DkDateEntity> firstDkList = kqbbMapper.queryDk(date,key); // 泛微获取到所有人打卡数据
		Map<String, SortedSet<String>> dkMap = new HashMap<>(); // 当月所有人打卡日期
		for (DkDateEntity dkDateEntity : firstDkList) {
			String workCode = dkDateEntity.getWorkcode(); // 工号
			String dkDate = dkDateEntity.getDkdate(); // 打卡日期
			String name = dkDateEntity.getName(); // 姓名
			if (dkMap.containsKey(workCode)) { // 存在更新日期set值
				SortedSet<String> newDateList = dkMap.get(workCode);
				newDateList.add(dkDate);
				dkMap.put(workCode, newDateList);
			} else { // 不存在创建日期list值
				SortedSet<String> dkDateList = new TreeSet<String>();
				dkDateList.add(dkDate);
				dkMap.put(workCode, dkDateList);
				worknamAndNameMap.put(workCode, name);
			}
		}
		System.out.println("dkMap:" + dkMap);
		// 当月考勤标准 得到工作日gzrList，休息日xxrList
		List<String> gzrList = new ArrayList<String>();
		List<String> xxrList = new ArrayList<String>();
		List<KqBzEntity> kqbzList = querykqBz(date); // 以董事长为基准，获取当月应考勤日期
		for (KqBzEntity item : kqbzList) {
			if (item.getSerialid() == null) {
				xxrList.add(item.getKqdate()); // 休息日
			} else if (item.getSerialid() == 1) {
				gzrList.add(item.getKqdate());// 工作日
			}

		}
		List<JiaBanEntity> jbList = queryJiaBanLiuCheng(date); // 加班流程、加班计划流程集合

		Map<String, List<String>> jbMap = getJbMap(jbList);// 处理加班流程、加班计划流程数据，变为Map(工号，日期集合) 即jbMap
		System.out.println("jbMap:" + jbMap);
		/**
		 * 根据 打卡Map:dkMap<工号,打卡日期集合> 加班Map:jbMap<工号，日期集合> 休息日List xxrList<日期>
		 * 将没有加班流程的日期去除
		 */

		for (Map.Entry entry : dkMap.entrySet()) {
			String mapKey = (String) entry.getKey();
//			System.out.println("mapKey:" + mapKey);
			Set<String> mapValueSet = (Set<String>) entry.getValue();// 获取了这个人所有的打卡日期集合
			if (jbMap.get(mapKey) != null) {
				List<String> newJbList = jbMap.get(mapKey); // 获取了这个人所有的加班日期
//				System.out.println("newJbList:" + newJbList);
				for (String xxr : xxrList) {
					if (mapValueSet.contains(xxr)) { // 有休息日打卡，去查询加班
						if (newJbList.contains(xxr)) { // 有加班
							// 无操作
						} else {
							mapValueSet.remove(xxr);
						}
					} else { // 无休息日打卡，不做操作

					}
				}
			} else { // 无加班流程的人，直接去除所有的xxr打卡记录
				mapValueSet.removeAll(xxrList);
			}
		}

		/**
		 * 重新返回List<JbtsEntity>给前端
		 */
		List<JbtsEntity> jbtsList = new ArrayList();
		for (Map.Entry entry : dkMap.entrySet()) {
			JbtsEntity jbts = new JbtsEntity();
			String gh = (String) entry.getKey();
			Set<String> mapValueSet = (Set<String>) entry.getValue();// 获取了这个人所有的打卡日期集合
			jbts.setWokecode(gh);
			jbts.setName(worknamAndNameMap.get(gh));
			jbts.setTs(mapValueSet.size());
			jbts.setDates(mapValueSet);
			jbtsList.add(jbts);
		}

		return jbtsList;
	}

	/**
	 * 交补天数导出
	 */
	@Override
	public String jbtsExport(String day, String key) {
		String name = "jbts" + System.currentTimeMillis() + ".xlsx";
		String fileName = CommonConfig.getProfile() + name;
		List<JbtsEntity> jblist = queryJbts(day, key);
		List<JbtsExcel> list = ListUtils.newArrayList();
		for (JbtsEntity item : jblist) {
			JbtsExcel jbtsExcel = new JbtsExcel();
			jbtsExcel.setName(item.getName());
			jbtsExcel.setWokecode(item.getWokecode());
			jbtsExcel.setTs(item.getTs());
			list.add(jbtsExcel);
		}
		// 写入数据
		EasyExcel.write(fileName, JbtsExcel.class).sheet().doWrite(list);
		return name;
	}

//end
}
